/*
 * db_mysql.cpp
 *
 *  Created on: 2016年12月6日
 *      Author: work
 */

#include <dm/os/db/db_mysql.hpp>
#include <cppconn/exception.h>
#include <cppconn/statement.h>
#include <cppconn/sqlstring.h>
#include <dm/os/log/logger.hpp>

namespace dm{
namespace os{

static const char* logModule = "CDbMysql.os.dm";

CDbMysql::CDbMysql( const char* dbName,const char* host ):CDb(dbName,host){
	m_driver = NULL;
	m_con = NULL;
}

CDbMysql::~CDbMysql(){
	if( m_con!=NULL )
		delete m_con;
}

CDb::EDbType CDbMysql::dbType(){
	return DtMysql;
}

bool CDbMysql::isConnected(){
	if( m_con!=NULL )
		return m_con->isValid();
	return false;
}

bool CDbMysql::connect( const char* user,const char* pw ){
	try {
		if (m_driver == NULL)
			m_driver = get_driver_instance();
		if (m_driver == NULL){
			log().error(logModule,this,__FUNCTION__,"获取数据库驱动失败");
			return false;
		}

		if( m_con==NULL ){
			m_con = m_driver->connect(m_host.c_str(),user,pw);
			if( m_con==NULL ){
				log().error(logModule,this,__FUNCTION__,"连接数据库失败%s@%s",user,m_host.c_str());
				return false;
			}

			m_con->setSchema(m_dbName.c_str());
			return true;
		}else{
			m_con->setSchema(m_dbName.c_str());
			return m_con->reconnect();
		}			
	}
	catch (sql::SQLException &e) {
		log().error(logModule,this,__FUNCTION__,"%s",e.what());
		return false;
	}

	return false;
}

void CDbMysql::disconnect( ){
	try {
		if( m_con )
			m_con->close();
	}
	catch (sql::SQLException &e) {
		log().error(logModule,this,__FUNCTION__,"%s",e.what());
	}

	if( m_con ){
		delete m_con;
		m_con = NULL;
	}
}

bool CDbMysql::exec( const char* sql ){
	sql::Statement* stmt = NULL;
	if( isConnected() ){
		try{
			stmt = m_con->createStatement();
			if( stmt==NULL ){
				log().error(logModule,this,__FUNCTION__,"准备语句失败");
			}else{
				stmt->execute(sql);
				delete stmt;
				return true;
			}
		}catch (sql::SQLException &e) {
			log().error(THISMODULE "错误编码:%d, %s[%s]",e.getErrorCode(),e.what(),sql);
			if( e.getErrorCode()==1043 || e.getErrorCode()==2006 )
				disconnect();
		}
	}else{
		log().warnning(logModule,this,__FUNCTION__,"没有连接");
	}

	if( stmt )
		delete stmt;

	return false;
}

CResultSet* CDbMysql::query( const char* sql ){
	if( isConnected() ){
		try{
			sql::Statement* stmt = m_con->createStatement();
			if( stmt==NULL ){
				log().error(logModule,this,__FUNCTION__,"准备语句失败");
			}else{
				sql::ResultSet* rt = stmt->executeQuery(sql);
				if( rt!=NULL ){
					CResultSetMysql* rs = new CResultSetMysql();
					rs->set(rt,stmt);
					return rs;
				}else{
					log().error(logModule,this,__FUNCTION__,"执行语句失败%s",sql);
					delete stmt;
				}
			}
		}catch (sql::SQLException &e) {
			log().error(logModule,this,__FUNCTION__,e.what());
			return NULL;
		}
	}

	return NULL;
}

/**
 * 获取匹配字符串表名
 * @param pattern
 * @param rs
 * @return
 */
CResultSet* CDbMysql::getTables( const char* pattern ){
	std::string sql = "select table_name from information_schema.tables where table_type='BASE TABLE' and table_name like '";
	sql += pattern;
	sql += "'";

	return query(sql.c_str());
}

}
}



